﻿using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Xml.Linq;


using System.Collections.Generic;
public partial class 数据算法_排队报数的算法 : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        int n = 50;//报数人
        int m = 3;//报数范围

        Queue<int> num = new Queue<int>(n);
        while (n-- > 0)
        {
            num.Enqueue(n);
            for (int i = 1; i < m; i++)
            {
                num.Enqueue(num.Dequeue());
            }
            
        }
    
    Response.Write(string.Format("最后一个人是{0}",num.Count-Array.IndexOf<int>(num.ToArray(),num.Count-1)));
    }
    // 这个报数很像一种翻扑克牌游戏
    // 这里假设只剩最后 1 人，然后倒推回 100 人都在
    // 受 Queue 右进左出的限制，假设报数是从右往左进行的比较好理解
    // 每次在右边补充进去出列的 1 人，就从左边挪出两个人补到右边
    // 补充人时， n 表示该人出列的顺序
    // 很多人对挪两个人的做法难以理解，那你可以假设有 5 个人报数的情景，
    // 3 号出列后，我们让 4 号 5 号挪到队伍开头，然后全队从 1 开始报号
    // 这个过程倒推回去就是本程序的想法。        

    /* 你可以把这段代码加在程序最后，进行验证。    

        n = num.Count;
        int[] result = new int[n];
        foreach (int i in num)
            result[i] = n--;
        foreach (int i in result)
            Console.WriteLine("第{0}个人出列.", i);
    */

}
